package com.ware4u.fx.news.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ware4u.fx.core.commons.resp.Result;
import com.ware4u.fx.news.dao.NewsRepository;
import com.ware4u.fx.news.entity.News;
import com.ware4u.fx.news.vo.NewsVO;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@Tag(name = "NewsController", description = "新闻接口")
@RequestMapping(value = "/api/news")
public class NewsController {
	@Resource
	private NewsRepository newsRepository;


	@Operation(summary = "获取所有新闻列表", description = "{{ base_url }}/api/news/query/null?page=5&size=20")
	@GetMapping(value = "/query/{keyword}")
	public Page<NewsVO> query(
			@Parameter(description = "关键字|null") @PathVariable("keyword") String keyword,
			@PageableDefault(value = 15, sort = { "id" }, direction = Sort.Direction.ASC) Pageable pageable) {
		Page<News> page = newsRepository.findAll((root, query, cb) -> {
			String likePattern = String.format("%%%s%%", keyword);
			List<Predicate> predicates = new ArrayList<>();
			if (StringUtils.isNotEmpty(keyword) && !"null".equalsIgnoreCase(keyword)) {
				predicates.add(cb.like(root.get("title"), likePattern));
			}
			return cb.and(predicates.toArray(new Predicate[0]));
		}, pageable);
		return page.map(n -> new NewsVO(n));
	}


	@Operation(summary = "根据板块名称获取板块内的新闻列表", description = "{{ base_url }}/api/news/catalog/null?page=5&size=20")
	@GetMapping(value = "/catalog/{name}")
	public Page<NewsVO> catalog(
			@Parameter(description = "板块名称") @PathVariable("name") String name,
			@PageableDefault(value = 15, sort = { "id" }, direction = Sort.Direction.ASC) Pageable pageable) {
		Page<News> page = newsRepository.findByCatalog(name, pageable);
		return page.map(n -> new NewsVO(n));
	}


	@Operation(summary = "可修改新闻的标题、内容、板块、来源")
	@GetMapping(value = "/item/{id}")
	public ResponseEntity<?> getNews(
			@Parameter(description = "新闻id") @PathVariable("id") Long id) {
		Optional<News> opt = newsRepository.findById(id);
		if (!opt.isPresent()) {
			return ResponseEntity.badRequest().body("未找到指定新闻内容！");
		}
		NewsVO vo = new NewsVO(opt.get());
		vo.setContent(opt.get().getContent());
		return ResponseEntity.ok(vo);
	}


	@Operation(summary = "可修改新闻的标题、内容、板块、来源（需要管理员权限）注：时间无法修改")
//	@PreAuthorize("hasRole('ROLE_ADMIN')")
	@PutMapping(value = "/update")
	public ResponseEntity<?> update(
			@Parameter(description = "新闻对象") @RequestBody NewsVO vo) {
		SecurityContext securityContext = SecurityContextHolder.getContext();
		String name = securityContext.getAuthentication().getName();

		Optional<News> opt = newsRepository.findById(vo.getId());
		if (!opt.isPresent()) {
			return ResponseEntity.badRequest().body("未找到指定新闻内容！");
		}
		News item = opt.get();
		item.setTitle(vo.getTitle());
		item.setContent(vo.getContent());
		item.setCatalog(vo.getCatalog());
		item.setSource(vo.getSource());
		item.setModifier(name);
		item.setModifyTime(new Date());

		newsRepository.save(item);
		return ResponseEntity.ok("");
	}


	@Operation(summary = "根据id删除某个新闻（需要管理员权限）")
//	@PreAuthorize("hasRole('ROLE_ADMIN')")
	@DeleteMapping(value = "/delete/{id}")
	public ResponseEntity<?> delete(
			@Parameter(required = true, name = "id", description = "新闻id") @PathVariable("id") Long id) {
		Optional<News> opt = newsRepository.findById(id);
		if (!opt.isPresent()) {
			return ResponseEntity.badRequest().body("未找到指定新闻内容！");
		}
		newsRepository.delete(opt.get());
		return ResponseEntity.ok("");
	}


	@Operation(summary = "增加一条新闻（需要管理员权限）")
//	@PreAuthorize("hasRole('ROLE_ADMIN')")
	@PostMapping(value = "/addnew")
	public ResponseEntity<?> addnew(
			@Parameter(required = true, description = "新闻对象") @RequestBody NewsVO vo) {
		SecurityContext securityContext = SecurityContextHolder.getContext();
		String name = securityContext.getAuthentication().getName();

		Result<?> result = validate(vo);
		if (!result.isResult()) {
			return ResponseEntity.badRequest().body(result.getMessage());
		}
		News news = new News();
		news.setCatalog(vo.getCatalog());
		news.setTitle(vo.getTitle());
		news.setContent(vo.getContent());
		news.setSource(vo.getSource());
		news.setCreator(name);
		news.setCreateTime(new Date());
		newsRepository.save(news);
		return ResponseEntity.ok("");
	}

	@Operation(summary = "模糊查询新闻标题 展示下拉选", description = "{{ base_url }}/api/news/fuzzyQueryTitle/")
	@GetMapping(value = "/fuzzyQueryTitle/{title}")
	public ResponseEntity<?> query(
			@Parameter(required = true, description = "新闻标题") @PathVariable("title") String title){

		if (StringUtils.isEmpty(title)) {
			throw new RuntimeException("/api/news/fuzzyQueryTitle/"+"传入的参数title为空");
		}
		List<News> newsList = newsRepository.findByTitleContaining(title);
		ArrayList<String> nameList = new ArrayList<>();
		for (News news : newsList) {
			nameList.add(news.getTitle());
		}
		return ResponseEntity.ok(nameList);
	}

	private Result<?> validate(NewsVO news) {
		if (StringUtils.isEmpty(news.getTitle())) {
			return Result.fail("标题不能为空！");
		}
		if (StringUtils.isEmpty(news.getContent())) {
			return Result.fail("内容不能为空！");
		}
		if (StringUtils.isEmpty(news.getCatalog())) {
			return Result.fail("新闻板块不能为空！");
		}
		return Result.success();
	}
}
